home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-11-01 | 36.3 KB | 1,402 lines |
- ;Chart V1.23 Copyright 1992-1993 Andrew Sprott
-
- ;The source files:
-
- ; CMAIN.86
- ; CFLOW1.86
- ; CFLOW2.86
- ; CSUB1.86
- ; CSUB2.86
- ; CSUB3.86
- ; CSYS.86
- ; CWORK.86
-
- ;should be accompanied with the file CHART.PJT, which is a PcWord version 1
- ;project file and contains the tabs and hypertext data for each source file.
- ;Make sure all of the files are in the same directory and PCWORD.EXE or
- ;HYPEREAD.COM is within the scope of the DOS PATH and enter:
-
- ; PCWORD CHART.PJT
-
- ;or load CHART.PJT from within PcWord.
-
- ;or enter
-
- ; HYPEREAD CHART.PJT
-
- ;To assemble CHART, you requires A86.COM version 3.21 or higher.
- ;Make sure the source files (*.86) and the file CHART. are in the same
- ;directory. Then assemble with the line
-
- ;A86 +E <CHART. &
-
- ;You may have noticed that the source file CPRINT.86 isn't included in the list
- ;above. This is because the printing function is incomplete as I gave up on it.
- ;The rest of the program works ok though.
-
- ;equates
-
- pull equ pop
- pullf equ popf
- o equ offset
-
- ;equates
-
- ;Each box has a record and a descripter string. The record is defined as below.
- ;The colour scheme for box record elements is GREEN
-
- previous equ 0 ;box lead from
- yes equ 2 ;yes route or single route
- no equ 4 ;no route
- child equ 6 ;child flowchart, 0 if none
- parent equ 8 ;parent box
- descripter_length equ 10 ;size of descripter string
- descripter equ 12 ;descripter 20 bit address
- box_temp equ 16 ;temporary store (used by renumber and
- ;printing routines)
- box_record equ 18 ;size of box record
-
- ;Other box references are light GREEN
-
- first_box equ 6 ;first box number
- box_top equ 16383-first_box ;highest box allowed
-
- option_count equ 22 ;total number of options available
- menu_options equ 6 ;menu option count
-
- ;All box stack references are RED
-
- top_stack equ 0fffch ;offset to top of subchart stack
- bottom_stack equ 0f000h ;allow 4096 for box stack
-
- novid equ 7 ;normal video attribute
- revid equ 070h ;reverse video attribute
-
- crtc_cstart equ 0ah ;cursor start address register
- crtc_cend equ 0bh ;cursor end address register
-
- crtc_clochigh equ 0eh ;cursor location msw
- crtc_cloclow equ 0fh ;cursor location lsw
-
- code segment
-
- call head ;initialise program
- main:
- call body ;goto main loop
- call tail ;check if flowchart needs saving
- jc main ;go back to main menu if escape pressed
-
- ;exit
-
- exit:
- call restore_cursor ;restore cursor type
- mov ax,04c00h ;load function parameters
- int 021h ;exit
-
- ;set up stack
-
- c1:
- pull bp ;load return address
- mov ax,w[2] ;load ram top segment
- sub ax,01000h ;subtract a segment from it
- cli ;disable interrupts
- mov sp,-2 ;store stack pointer
- mov ss,ax ;store stack segment
- sti ;enable interrupts
-
- ;calculate ram top
-
- sub ax,0100h ;leave 4k for stack
- mov w stack_segment,ax ;store it as top of subchart stack
- sub ax,0100h ;allow 4k for box stack
- xor si,si ;convert stack pointer to address
- call ptr_addr
- mov w ram_top,ax ;save it
- mov w ram_top+2,dx
-
- ;initialise chart flags
-
- mov ax,si ;load zero
- mov b chart_flag,al ;start at beggining of editing loop
- mov b search_string,al ;clear search string buffer
- mov w next_box,ax ;indicate no chart loaded
- mov w current_box,ax
-
- ;calculate address of start of box records
-
- mov ax,cs ;load code segment
- xor dx,dx ;extend accumulator
- shl ax,1 ;convert segment to address
- rcl dx,1
- shl ax,1
- rcl dx,1
- shl ax,1
- rcl dx,1
- shl ax,1
- rcl dx,1
- add ax,o start_of_chart ;add program size
- adc dx,0
- mov w chart,ax ;store address to start of box data
- mov w chart+2,dx
- mov w start_free_memory,ax ;store address to box descripter store
- mov w start_free_memory+2,dx
-
- ;set screen mode as 80 column text mode
-
- call init_screen ;initialise screen
- mov w exit_cursor_type,cx ;save type of cursor
- push bp ;save return address
- xor dx,dx ;load zero
- mov di,o filename ;load offset to filename buffer
- xchg dx,w[di] ;is a flowchart filename supplied?
- or dx,dx
- je ret ;exit if not
-
- ;copy filename to flowchart
-
- mov si,dx ;copy offset to start of filename
- mov es,ax,cs ;copy segment to buffer
- a1:
- lodsb ;load character from filename
- stosb ;write to filename buffer
- or al,al ;end of filename?
- jne a1 ;copy next character if not
- call load_chart_dx ;load alternative chart if yes
- ret ;exit to body if not
-
- ;initialise program
-
- head:
- xor ax,ax ;load zero
- mov b middle_5,al ;indicate not in shell
- mov w filename,ax ;indicate no filename supplied
- dec ax
- mov b new_chart,al
- mov b direct_video,al ;indicate writing direct to video
-
- ;copy crtc address for current display mode
-
- inc ax ;load zero
- mov ds,ax ;copy segment to bios workspace
- mov ax,w[0463h] ;copy crtc address to whatever is active
- mov ds,dx,cs ;restore segment register
- mov w crtc_address,ax
-
- ;set defaults
-
- xor cx,cx ;load zero
- mov b display_type,cl ;indicate fit to whatever display
- mov b chart_active,0ffh ;indicate chart is active
- mov si,o 080h ;load offset to command tail
- mov cl,b[si] ;load size of command tail
- jcxz >c2 ;set up stack if no arguments
- inc si ;move to first character in command tail
-
- ;check if arguments are recognised
-
- b1:
- lodsb ;move to next non white-space character
- cmp al,020h ;is character white-space?
- if be loop b1 ;read next character if not
- cmp al,'/' ;start of argument?
- loopne b1 ;read next character if not
- jcxz >c2 ;set up stack if no more arguments
-
- ;check if argument is /m for remain displaying on a monochrome display
-
- b2:
- lodsb ;load argument switch
- and al,05fh ;make it upper case
- mov dl,7 ;assume specifying monochrome display
- mov bx,03b4h ;load crtc address for MDA
- cmp al,'M' ;is it m for monochrome?
- je >a1 ;store option if it is
- mov dl,3 ;assume option is colour
- mov bx,03d4h ;load crtc address for CGA
-
- ;load whatever crtc address if no display type specified
-
- cmp al,'C' ;is it c for colour?
- jne >a2 ;check for H for help if not
- a1:
- mov w crtc_address,bx ;save crtc port address
- mov b display_type,dl ;store display type
- jmp >c2 ;setup stack
-
- ;mark end of filename and check next argument
-
- a5:
- mov b[si-1],0 ;mark end of filename
- jmp b2 ;check next argument
- c2:
- jmp c1 ;setup stack
-
- ;move to start of filename
-
- a3:
- inc si ;move to next character
- a4:
- cmp b[si],020h ;is next character white space?
- loope a3 ;move to next character if it is
- je c2 ;setup stack if end of command line
-
- ;store zero byte at end of filename
-
- mov w filename,si ;mark start of filename
- a1:
- lodsb ;move to next character
- cmp al,'/' ;is character switch?
- je a5 ;mark end of filename if it is
- cmp al,020h ;is character white space?
- jbe >a5 ;mark end of filename if yes
- loop a1 ;move to next character if not
-
- ;mark end of filename
-
- mov b[si],0 ;mark end of filename
- jmp c2 ;initialise environment
- a5:
- mov b[si-1],0 ;mark end of filename
- jmp b1 ;check next item on command line
-
- ;check for command line help
-
- a2:
- cmp al,'F' ;is argument a filename?
- je a4 ;check for help if not
- a2:
- cmp al,'H' ;display banner?
- je >b1 ;display and exit if yes
- cmp al,'?' ;display banner?
- jne c2 ;setup stack
-
- ;get display page
-
- b1:
- xor ax,ax ;load zero
- mov es,ax
- es mov al,b[0462h] ;copy current active video page
- mov b active_page,al
- call get_screen ;initialise pointers to current mode
-
- ;get cursor position
-
- mov ah,3 ;load function parameter
- mov bh,b active_page ;load current page
- call int10 ;read cursor position
- xor dl,dl ;load column 1
- call copyright_message ;display copyright banner
-
- ;display invocation syntax
-
- call write ;write title
- db 13,13,'USAGE: CHART /M /H or /?',13
- db '/M stick with monochrome display',13
- db '/C stick with colour display',13
- db '/H or /? this banner',13,0
- mov ax,04c00h ;exit back to calling process
- int 021h ;transfer to DOS
-
- ;main loop
-
- body:
- mov ds,ax,cs ;copy segment to workspace
- call clear_cursor ;clear cursor
- call cls ;clear the screen
- mov dx,0509h ;load cursor coords
- call copyright_message ;display copyright banner
-
- ;write save flowchart option
-
- mov dx,0917h ;position cursor for first option
- call cursor
- mov al,' ' ;clear option character
- cmp b new_chart,0ffh ;is there a chart in memory?
- je >a1 ;write option character if not
- cmp b chart_active,080h ;is chart in interrupt?
- if ne mov al,'1' ;load option character
- a1:
- mov b menu,al ;indicate option available
- call write_chr ;write option character to screen
-
- ;write save options
-
- call write ;write save option
- db ': Save flowchart',0
- mov bx,'3 ' ;load option characters
- cmp b chart_active,080h ;is chart in interrupt?
- if ne mov bl,'2' ;load option character
- mov w menu+1,bx ;indicate options available
- mov al,bl ;load load file option char
- mov dx,0b17h ;load cursor coords
- call cursor ;position cursor
- call write_chr ;write it to screen
- call write ;write next option character
- db ': Load flowchart',0
-
- ;write edit options
-
- call writexy ;write edit option
- db 23,13
- db '3: Edit flowchart',0
- mov bl,' ' ;clear new chart and print chart options
- cmp b new_chart,0ffh ;is there a flowchart in memory?
- if ne mov bl,'4'
- mov w menu+3,bl ;indicate options available
-
- ;write clear flowchart option
-
- mov dx,0f17h ;load cursor coordinates
- call cursor ;position cursor
- mov al,bl ;load option
- call write_chr ;write it to screen
- call write ;write clear flowchart option
- db ': Clear flowchart',0
-
- ;write print flowchart option
-
- ; mov dx,0f17h ;load cursor coordinates
- ; call cursor ;position cursor
- ; mov al,b menu+4 ;load option
- ; call write_chr ;write it to screen
- ; call write ;write clear flowchart option
- ; db ': Print flowchart',0
-
- ;write dos shell option to screen
-
- mov al,' '
- cmp b chart_active,080h ;is chart in interrupt?
- if ne mov al,'5' ;load option character
- mov b menu+4,al ;store it
- mov dx,01117h ;load cursor coords
- call cursor ;position cursor
- call write_chr ;write option character
- call write ;write dos shell option
- db ': Dos shell',0
-
- ;write exit option
-
- call writexy ;write exit option
- db 23,19
- db '6: Exit',0
- mov b menu+5,'6' ;indicate option available
- call writexy
- db 20,23
- db 'ESC will bring you back here',0
-
- ;fetch keypress
-
- b1:
- call key ;get keypress
- jnc >a1 ;check if keypress is control code
- cs mov b middle_5,0 ;cancel quick exit flag
- jmp b1 ;get another key if middle 5 down
-
- ;check keypress
-
- a1:
- cmp al,020h ;is char control code?
- jbe b1 ;get another keypress if it is
- mov cx,menu_options ;load total menu options
- mov di,o menu ;load pointer to option string
- mov es,bx,cs
- repne
- scasb
- jne b1 ;get another keypress if not a option
-
- ;check if keypress is for save chart option
-
- cmp al,'1' ;is it?
- jne >a2 ;check for load chart option if not
- call save_chart ;save flow chart to disk
- jmp body ;goto start of main loop
-
- ;check if keypress is for load chart option
-
- a2:
- cmp al,'2' ;is it?
- jne >a2 ;check for edit chart option if not
- call load_chart ;load flow chart from disk
- mov ds,ax,cs ;restore data segment register
- jnc >c1 ;rejoin main loop if ok
- cmp w current_box,0 ;is there a chart resident
- je >e2 ;reset variables if not
- c1:
- jmp body ;rejoin main loop if there is
-
- ;check if keypress is for edit chart option
-
- a2:
- cmp al,'3' ;is it?
- jne >a2 ;check for clear chart option if not
- mov bp,w current_box ;load current box
- call check_memory ;check if enough memory
- jc >a1 ;return to main loop if not enough space
-
- ;call main editing loop
-
- call flowchart ;save flow chart to disk
- jc >a3 ;exit if middle 5 down
- or bp,bp ;normal exit?
- je >e2 ;reset flowchart if error
- a1:
- jmp body ;goto start of main loop if yes
-
- ;exit
-
- a3:
- clc ;indicate ok
- ret ;exit
-
- ;reset flowchart
-
- e2:
- mov ds,ax,cs ;load segment to workspace
- mov es,ax
- xor ax,ax ;load zero
- mov b chart_flag,al
- mov w next_box,ax ;set next vacant box
- mov w current_box,ax
-
- ;clear bookmarks
-
- mov cx,10 ;load bookmark count
- mov di,o bookmarks
- rep
- stosw ;clear them
- dec al
- mov b new_chart,al ;clear chart
-
- ;reset address to free memory
-
- mov ax,w chart ;load base address
- mov dx,w chart+2
- mov w start_free_memory,ax ;store it as start of free memory
- mov w start_free_memory+2,dx
- a1:
- jmp body ;goto menu
-
- ;check if keypress is for clear chart option
-
- a2:
- cmp al,'4' ;is it?
- jne >a2 ;check for shell option if not
- call tail ;check if chart has been saved
- jc a1 ;redo menu if escape pressed
- jmp e2 ;clear chart
-
- ;check if keypress is for print chart option
-
- ;a2:
- ; cmp al,'5' ;is it?
- ; jne >a2 ;check for dos shell option if not
- ; call print_chart ;print chart;
- ; jmp body ;goto start of main loop
-
- ;check if keypress is for dos shell option
-
- a2:
- cmp al,'5' ;is it?
- jne >a2 ;exit if not
- jmp dos_shell ;exit to dos shell
-
- ;check for exit option
-
- a2:
- cmp al,'6' ;is keypress for exit?
- je ret ;exit if it is
- jmp b1 ;get another keypress
-
- ;check if flowchart has changed since last save
-
- tail:
- cmp b chart_active,080h ;is chart in interrupt?
- je ret ;exit if it is
- cmp b new_chart,080h ;is there a chart in memory?
- jae ret ;dont prompt to save it if not
- call clear_line ;clear bottom lines
- call writexy ;write save message to screen
- db 24,24
- db 'Flowchart not saved, save (y/n)',0
-
- ;wait for keypress
-
- a2:
- call key ;get keypress
- jnc >a1 ;check if keypress is control code
- cs mov b middle_5,0 ;cancel quick exit flag
- jmp a2 ;wait for next keypress
- a1:
- stc ;indicate escape pressed
- je ret ;exit if escape pressed
-
- ;check if user wants to save
-
- and al,05fh ;make keypress upper case
- cmp al,'N' ;does user want to save
- je ret ;exit if not
- cmp al,'Y' ;save?
- jne a2 ;get another keypress if not
- call save_chart ;save flowchart
- ret ;exit
-
- ;save flowchart to disk
-
- save_chart:
- call filename_prompt ;write prompt to bottom line
- call get_string ;get filename
- dw filename ;offset to string buffer
- db 64,1 ;maximum string size
- jc ret ;exit if escape pressed
-
- ;open file for writing
-
- mov dx,si ;load offset to filename
- mov ah,03ch ;load function parameter
- xor cx,cx ;load file attribute
- int 021h ;create file
- jnc >a1 ;subtract base from descripter
- ;addresses if file created
- call error_exit ;exit with error
- db 30,'File creation error',0
-
- ;save current box and next new box markers
-
- a1:
- mov w handle,ax ;save handle
- mov bx,ax
- mov ah,040h ;load function parameter
- mov cx,4 ;load count
- mov dx,o current_box
- int 021h ;write current box and new box to disk
- jc >b2 ;exit if error
-
- ;subtract base of chart data area from descripter addresses
-
- a1:
- mov bx,w chart ;load base address
- mov dx,w chart+2 ;load high word of base address
- not bx ;convert to 2s complement
- not dx
- inc bx
- if e inc dx ;increment if carry
- call chart_addresses ;subtract base from chart addresses
-
- ;calculate size of data area
-
- mov ax,w start_free_memory ;load ram top address
- mov dx,w start_free_memory+2
- mov bx,w chart ;load base address
- mov cx,w chart+2
- sub ax,bx ;calculate size of data area
- sbb dx,cx
- mov w shift_count,ax ;save it
- mov w shift_count+2,dx
- mov w temp2,bx ;save address of data
- mov w temp2+2,cx
-
- ;write box data and descripters store to disk
-
- b1:
- call load_count ;get size of block
- mov si,cx ;save it
- mov ax,w temp2 ;load start address of block
- mov dx,w temp2+2
- call get_pointer ;convert it to pointer format
- mov dx,di ;load offset
- mov bx,w handle ;load handle to output file
- mov ds,ax,es ;copy segment
- mov ah,040h ;load function parameter
- int 021h ;write block to disk
-
- ;check for error
-
- mov di,cs ;restore data segment register
- mov ds,di
- mov bx,w handle ;load handle to output file
- jnc >a1 ;check if all bytes were written if ok
-
- ;close file and exit with error message
-
- b2:
- mov ah,03eh ;load function paramter
- int 021h ;close file
- call error_exit ;exit with error
- db 31,'Cant write to disk',0
-
- ;check if all bytes were written to file
-
- a1:
- cmp ax,si ;were they?
- je >a1 ;check if any more bytes to write if yes
- mov ah,03eh ;load function parameter
- int 021h ;close file
- call error_exit ;exit with error message
- db 35,'Disk full',0
-
- ;check if any more bytes to write
-
- a1:
- add w temp2,si ;add bytes written to address
- adc w temp2+2,0
- mov ax,w shift_count ;is there any more bytes to write
- or ax,w shift_count+2
- jne b1 ;write next block if there is
-
- ;restore box addresses to descripters
-
- mov ah,03eh ;load function parameter
- int 021h ;close file
- mov bx,w chart ;load base address
- mov dx,w chart+2 ;load high word of base address
- or b new_chart,080h ;indicate chart saved
-
- ;subtract/add chart base address to box descripter addresses
-
- chart_addresses:
- mov cx,w next_box ;load top box
- mov ax,first_box ;load first box
- sub cx,ax ;calculate number of boxes in chart
- jcxz ret ;exit if chart empty
- call get_box ;get its pointer
-
- ;check if box is deleted
-
- a1:
- es cmp w[di],-1 ;is this box deleted?
- je >a3 ;move to next box if it is
- mov si,20 ;load offset to bookmarks
- es mov w[di+box_temp],0 ;clear bookmark marker
-
- ;check if current box is boxmarked
-
- a2:
- sub si,2 ;move back a bookmark
- jc >a4 ;update descripter address if not marked
- cmp ax,w[si+bookmarks] ;is current box marked?
- jne a2 ;check next bookmark if not
- shr si,1 ;calculate bookmark id
- inc si
- es mov w[di+box_temp],si ;indicate this box is marked
-
- ;update pointers
-
- a4:
- es add w[di+descripter],bx ;add/subtract base address
- es adc w[di+descripter+2],dx
- a3:
- inc ax ;increment box marker
- call add_record ;move to next box
- loop a1 ;decrement loop count
- clc ;indicate chart loaded/saved
- ret ;exit
-
- ;subtract/add chart base address to box descripter addresses
-
- chart_addresses2:
- mov ax,first_box ;load first box
- sub cx,ax ;calculate number of boxes in chart
- jcxz ret ;exit if chart empty
- call get_box ;get its pointer
-
- ;update pointers
-
- a1:
- es add w[di+descripter],bx ;add/subtract base address
- es adc w[di+descripter+2],dx
- call add_record ;move to next box
- loop a1 ;decrement loop count
- clc ;indicate chart loaded/saved
- ret ;exit
-
- ;subtract/add chart base address to box descripter addresses
-
- chart_bookmarks:
- mov ax,first_box ;load first box
- mov cx,w next_box ;calculate number of boxes in chart
- sub cx,ax
- jcxz ret ;exit if chart empty
- call get_box ;get its pointer
-
- ;update pointers
-
- a1:
- es cmp w[di],-1 ;is this box deleted?
- je >a3 ;move to next box if it is
- es mov si,w[di+box_temp] ;load box marker flag
- dec si ;correct it
- cmp si,9 ;is this box marked?
- ja >a3 ;update descripter if not
- shl si,1 ;calculate offset to bookmark
- mov w[si+bookmarks],ax ;store bookmark
-
- ;update descripter pointer
-
- a3:
- inc ax ;increment box marker
- call add_record ;move to next box
- loop a1 ;decrement loop count
- clc ;indicate chart loaded/saved
- ret ;exit
-
- ;write error message and exit
-
- error_exit:
- call clear_line ;clear bottom lines
- pull si ;load address of message
- lodsb ;load cursor coords
- mov dl,al
- mov dh,24
- call cursor ;position cursor
- a1:
- lodsb ;load character from message
- or al,al ;end of string?
- je >a2 ;wait for keypress if it is
- call write_chr ;write it to bottom line
- jmp a1 ;get next character
-
- ;wait for keypress
-
- a2:
- call key ;wait for keypress
- cs mov b middle_5,0 ;cancel quick exit flag
- stc ;indicate error
- ret ;exit
-
- ;write prompt to bottom line
-
- filename_prompt:
- call clear_line ;clear bottom lines
- call writexy ;write prompt
- db 27,24
- db 'Please enter path/filename',0
- ret ;exit
-
- ;exit from here if middle 5 on numeric keypad is down
-
- b1:
- cmp b middle_5,0 ;has it been pressed?
- je flowchart ;don't exit from here if not
- stc ;indicate middle 5 on keypad pressed
- ret ;exit if it has
-
- ;main editing loop
-
- flowchart:
- call get_options ;get options available
- a1:
- call write_chart ;write options and chart to screen
- call do_option ;process option select
- jc b1 ;get options if escape not pressed
- jne a1 ;write chart again if escape not pressed
- ret ;exit
-
- ;get string from keyboard input
-
- get_string:
- pull si ;get offset to string
- lodsw
- mov w start_string,ax ;save it
- lodsw ;read maximum string length
- push si ;save return address
- mov b escape_flag,ah ;store flag
- xor ah,ah ;clear high order register
- dec ax ;adjust it
- add ax,w start_string ;calculate offset to end of string
- mov w end_string,ax ;save it
-
- ;save cursor position
-
- push bx,di,es ;save pointer
- mov dx,01700h ;load cursor coordinates
- mov w edit_cursor,dx
- mov di,w start_string ;load offset to start of string
- mov es,ax,cs ;copy code segment
- mov w start_string_screen,di ;store it as start of string on screen
-
- ;position cursor
-
- c1:
- mov si,w start_string_screen ;load offset to start of string
- mov dx,01700h ;load position for start of string
- call cursor ;position cursor
- call clear_cursor ;clear cursor
- mov cx,79 ;load count
-
- ;write string to screen
-
- a1:
- lodsb ;load character from string
- or al,al ;end of string?
- je >a2 ;get keypress if it is
- call write_chr ;write character to screen
- loop a1 ;decrement loop count
-
- ;write spaces at end of string
-
- a2:
- jcxz >a1 ;position cursor in string if line full
- mov al,' ' ;finish off string with space
- a2:
- call write_chr
- loop a2 ;decrement loop count
-
- ;position cursor
-
- a1:
- mov cx,0ch ;load cursor rows
- call set_cursor ;set cursor type
- mov dx,w edit_cursor ;load cursor position
- call cursor ;position cursor
-
- ;get keypress
-
- c2:
- call key ;get keypress
- cs mov b middle_5,0 ;cancel quick exit flag
- jc c2 ;get another keypress
- jne >b1 ;check for right key if escape not down
- cmp b escape_flag,0 ;is escape enabled?
- je c2 ;get another key if not
- call clear_cursor ;clear the cursor
- pull es,di,bx ;restore pointer
- stc
- ret ;exit
-
- ;check for right arrow key
-
- b1:
- cmp ax,04d00h ;is keypress right key?
- jne >b1 ;check for left key if not
- call move_right ;move cursor right one space
- je c2 ;get keypress if at end of string
- jmp c1 ;display string
-
- ;check for left arrow key
-
- b1:
- cmp ax,04b00h ;is keypress left key?
- jne >b1 ;check for home if not
- call move_left ;move cursor left
- je c2 ;get keypress if at start of string
- jmp c1 ;display string
-
- ;check for home key
-
- b1:
- cmp ax,04700h ;is keypress home key?
- jne >b1 ;check for end if not
- a1:
- call move_left ;move cursor left
- jne a1 ;keep on moving until at start of string
- jmp c1 ;display string
-
- ;check for end key
-
- b1:
- cmp ax,04f00h ;is keypress left key?
- jne >b1 ;check for ctrl left if not
- a1:
- call move_right ;move cursor left
- jne a1 ;keep on moving until at start of string
- jmp c1 ;display string
-
- ;check for ctrl left arrow key (move cursor left a word)
-
- b1:
- cmp ax,07300h ;is keypress ctrl left key?
- jne >b1 ;check for ctrl right if not
- call move_left ;move left a character
- je c2 ;get keypress if at start of string
- mov w temp2,o move_left ;store calling address
- call ctrl_lr ;move to next word
- if ne call move_right ;move cursor over first chr in word
- jmp c1 ;display string
-
- ;check for ctrl right arrow key (move cursor right a word)
-
- b1:
- cmp ax,07400h ;is keypress ctrl right key?
- jne >b1 ;check for ctrl end if not
- mov w temp2,o move_right ;store calling address
- call ctrl_lr ;move to next word
- jmp c1 ;display string
-
- ;check for ctrl end key (delete to end of line)
-
- b1:
- cmp ax,07500h ;is keypress ctrl end key?
- jne >b1 ;check for return if not
- mov b[di],0 ;delete to end of string
- jmp c1 ;display string
-
- ;check for carriage return
-
- b1:
- cmp al,0dh ;is keypress carriage return?
- jne >b1 ;check for backspace if not
- mov si,w start_string ;load offset to start of string
- cmp b[si],0 ;is it empty?
- c3:
- if e jmp c2 ;get another keypress if it is
-
- ;calculate length of string
-
- push si ;save offset
- mov cx,-1 ;clear count
- a1:
- lodsb ;load character from string
- inc cx ;increment count
- or al,al ;end of string?
- jne a1 ;read next character
- call clear_cursor ;clear the cursor
- pull si,es,di,bx ;restore pointer
- ret ;exit
-
- ;check for backspace key
-
- b1:
- cmp ax,0e08h ;is keypress backspace key?
- jne >b1 ;check if it is delete key if not
- cmp di,w start_string ;is offset at start of string?
- je c3 ;get another keypress if it is
- dec di ;decrement offset
-
- ;decrement cursor column
-
- cmp b edit_cursor,0 ;is cursor at end of line?
- ja >a1 ;increment column coordinate if not
- dec w start_string_screen ;increment offset to start of string
- jmp >b2 ;write string to screen
- a1:
- dec b edit_cursor ;decrement cursor column
- jmp >b2 ;delete character at cursor
-
- ;check for delete key
-
- b1:
- cmp ax,05300h ;is keypress delete key?
- jne >b1 ;check if it is alphanumeric if not
- cmp b[di],0 ;is offset at end of string?
- je >c3 ;get another keypress if it is
- b2:
- mov bx,di ;load string offset
- dec bx ;adjust offset
- a1:
- inc bx ;increment offset
- mov al,b[bx+1] ;move next character down
- mov b[bx],al
- or al,al ;end of string?
- jne a1 ;move next character if not
- jmp c1 ;write string to screen
- c3:
- jmp c2 ;fetch another keypress
-
- ;check if keypress is alphanumeric
-
- b1:
- cmp al,020h ;is keypress with ctrl or alt key?
- jb c3 ;fetch another keypress if it is
- cmp di,w end_string ;is string full?
- je c3 ;fetch another keypress if it is
-
- ;insert character into string
-
- mov bx,w end_string ;load offset to end of string
- inc bx
- mov b[bx+1],0 ;mark end of string
- a1:
- dec bx ;decrement offset
- mov ah,b[bx] ;load character at end of string
- mov b[bx+1],ah ;move it up one
- cmp bx,di ;is offset at cursor position?
- ja a1 ;move next character if not
- stosb ;store character in string
-
- ;increment cursor column
-
- cmp b edit_cursor,79 ;is cursor at end of line?
- jb >a1 ;increment column coordinate if not
- inc w start_string_screen ;increment offset to start of string
- jmp c1 ;write string to screen
- a1:
- inc b edit_cursor ;increment cursor column
- jmp c1 ;write string to screen
-
- ;move cursor word left/right
-
- ctrl_lr:
- mov al,b[di] ;load character at cursor
- cmp al,' ' ;is it a space?
- if ne xor al,al ;search for next space if not
- mov dl,al ;load search character
- mov b temp3,0 ;store loop count
- xor dl,' ' ;flip flag
- if e inc b temp3 ;search for non space then space
-
- ;search for space/non space character
-
- a1:
- call w temp2 ;move cursor left/right
- je ret ;exit if at start/end of line
- mov al,b[di] ;load character at cursor
- cmp al,dl ;is it Space character?
- je >a3 ;check if at end of next word if it is
- cmp al,' ' ;is scan character non space?
- Je a1 ;decrement loop count if it is
- Cmp dl,' ' ;is scan character space?
- Je a1 ;decrement loop count if it is
-
- ;switch scan character
-
- a3:
- xor dl,' ' ;switch scan character
- dec B temp3 ;decrement loop count
- je a1 ;search for next space character if
- ;character was non space
- ret ;exit
-
- ;move cursor right one space
-
- move_left:
- cmp di,w start_string ;is string maximum size?
- je ret ;get another keypress if it is
- dec di ;decrement offset
- cmp b edit_cursor,0 ;is cursor at start of line?
- ja >a1 ;decrement column coordinate if not
- dec w start_string_screen ;decrement offset to start of string
- ret ;exit
- a1:
- dec b edit_cursor ;decrement cursor position
- or ax,di ;indicate cursor moved
- ret ;exit
-
- ;move cursor right one space
-
- move_right:
- cmp b[di],0 ;is cursor at end of string?
- je ret ;exit if it is
- cmp di,w end_string ;is string maximum size?
- je ret ;exit if it is
- inc di ;increment offset
- cmp b edit_cursor,79 ;is cursor at end of line?
- jb >a1 ;increment column coordinate if not
- inc w start_string_screen ;increment offset to start of string
- ret ;exit
- a1:
- inc b edit_cursor ;increment cursor position
- ret ;position cursor
-
- ;read cursor position coordinates and position cursor
-
- writexy:
- pull si ;load offset to cursor coords
- lodsw ;read cursor coords
- mov dx,ax
- c1:
- call cursor ;position cursor
- push si ;save offset to string
-
- ;write string following calling address
-
- write:
- pull si ;load offset to string
- mov bl,novid ;load attribute
- mov ah,bl
- mov b attribute,bl ;store darker colour
- push di,es ;save pointer
- les di,w video_pointer ;load pointer to video map
-
- ;read character from calling procedure
-
- b1:
- lodsb ;read character from string
- or al,al ;last character?
- jne >a1 ;check video flag if not
- mov w video_pointer,di ;save pointer to video map
- pull es,di ;restore pointer
- jmp si ;exit if it is
-
- ;check for carriage return
-
- a1:
- cmp al,13 ;carriage return?
- jne >a1 ;output character if not
- push ax,bx,cx,dx,si,di,bp ;save registers
- mov bx,w attribute ;load attribute and active page
- mov ah,0eh ;output carraige to bios teletype fn
- call int10 ;call bios
- mov ax,0e0ah ;output line feed
- call int10 ;call bios
- pull bp,di,si,dx,cx,bx,ax ;restore registers
-
- ;reposition video pointer
-
- mov dx,w cursorxy ;load cursor row position
- xor dl,dl ;set start of row
- cmp dh,24 ;is cursor on bottom row?
- if b inc dh ;move to next row if not
- jmp c1 ;read next character
-
- ;write character to screen
-
- a1:
- cmp b direct_video,0 ;write direct to video map?
- jne >a1 ;write char and attribute to map if yes
- call write_chr ;write character to screen
- jmp b1 ;read next character
- a1:
- stosw ;write chara and attribute to video map
- jmp b1 ;read next char
-
- ;write character to screen
-
- write_chr:
- push ax,bx,cx,dx,si,di,bp ;save registers
- cs mov bx,w attribute ;load active page
- cs cmp b direct_video,0 ;is screen output direct?
- je >a1 ;write char through bios if not
-
- ;write char direct to video memory
-
- push es ;save pointer
- cs les di,w video_pointer ;load pointer to video map
- mov ah,bl ;load attribute]
- stosw ;write it and char to video memory
- cs mov w video_pointer,di ;save pointer to video map
- pull es ;restore pointer
- jmp >a2
-
- ;write character via bios
-
- a1:
- mov ah,3 ;load function parameter
- push bx ;save register
- call int10 ;read cursor position
- mov ah,9 ;load funtion parameter
- pull bx ;load active page
- push dx,bx ;save registers
- mov cx,1 ;load character count
- call int10 ;print the character
- pull bx,dx ;restore page and cursor coords
- cmp dl,80 ;is it beyond right of screen
- if b inc dl ;increment x coordinate
- mov ah,2 ;load set cursor function parameter
- call int10 ;advance cursor
- a2:
- pull bp,di,si,dx,cx,bx,ax ;restore registers
- ret
-
- ;set 80x25 text display mode
-
- init_screen:
- push ds ;save register
- mov al,b display_type ;set 80x25 text display
- xor dx,dx ;load segment to bios workspace
- mov ds,dx
- or al,al ;fit with whatever display is in use?
- jne >a1 ;set display mode if not
- mov al,b[0449h] ;load video mode
- mov ah,al
- mov bh,b[0462h]
-
- ;set display mode
-
- cmp al,2 ;is display text (80x25)
- je >a2 ;set video map pointeers if it is
- cmp al,3 ;is current display mode text?
- je >a2 ;set video map pointeers if it is
- cmp al,7 ;is display monochrome?
- je >a2 ;set video map pointeers if it is
- mov al,3 ;set 80x25 text if not text mode
-
- ;force 80x25 colour text mode
-
- a1:
- call int10 ;call bios
- mov al,b[0449h] ;load video mode
- mov ah,al
- mov bh,b[0462h]
- jmp >a2 ;calculate pointers to video map
-
- ;set pointers to screen
-
- get_screen:
- push ds ;save register
- mov bh,b active_page ;load page last active
- mov al,b display_type ;load fixed display type
- xor dx,dx ;load segment to bios workspace
- mov ds,dx
-
- ;load currently displayed video mode
-
- mov ah,b[0449h] ;load video mode if yes
- or al,al ;is display fixed?
- jne >a2 ;calculate pointers to video map if yes
- mov al,ah ;load video mode if yes
- mov bh,b[0462h]
-
- ;store variables
-
- a2:
- mov dx,ax ;copy video modes
- sub dl,dh ;if displays are cga then count as same
- if c neg dl ;get difference
- cmp dl,3 ;is video mode cga?
- if be mov al,ah ;make both modes same
-
- ;store current video page
-
- cs mov b active_page,bh ;store it
- mov bl,b[0462h] ;calculate offset to cursor coordinates
- xor bh,bh
- shl bx,1
- mov dx,w[bx+0450] ;get cursor coords
- mov cx,w[0460] ;get cursor type
-
- ;calculate base address to current video mode
-
- mov bx,0b800h ;load video memory base address
- cmp al,3 ;is video mode for cga?
- if ne mov bx,0b000h ;load base video ram address for mda
- pull ds ;restore register
- mov w video_base,bx ;store video memory base address
- ret ;exit
-
- ;calculate offset to video memory
-
- cursor:
- push ax,bx,cx,dx,si,di,bp ;save registers
- cs mov bh,b active_page ;load video page
- cs mov w cursorxy,dx ;save cursor postion
- mov al,bh ;load video page
- cbw ;sign extend
- mov cl,12 ;multiply page by 4096
- shl ax,cl
- mov di,ax ;store it in offset
- mov al,dh ;load cursor row
- cbw ;sign extend
- push dx ;save cursor coords
- mov dx,ax ;save offset to start of page
- shl ax,1 ;x 2
- shl ax,1 ;x 4
- add ax,dx ;x 5
- mov cl,5 ;x 160
- shl ax,cl
- add di,ax ;add it to active page offset
- pull dx ;restore cursor coords
- mov al,dl ;load cursor coords
- cbw ;sign extend
- shl ax,1 ;multiply column offset by two
- add di,ax ;add it to active page and row
- cs mov w video_pointer,di ;save offset to video map
-
- ;position cursor
-
- cs cmp b chart_active,080h ;is program in dos shell?
- je >b1 ;program video hardware directly
- mov ah,2 ;load function parameter
- call int10 ;position cursor if not
- jmp >c1 ;exit
-
- ;program video hardware to position cursor
-
- b1:
- cs cmp b cursor_on,0 ;is cursor displayed?
- je >c1 ;exit if not
- b1:
- cs mov dx,w crtc_address ;load crtc register address port
- shr di,1 ;convert word address to byte address
- mov bx,di ;load cursor offset
-
- ;set cursor location address high word
-
- mov al,o crtc_clochigh ;load register address
- out dx,al
- mov al,bh ;copy msb to crtc
- inc dx
- out dx,al
- dec dx
-
- ;set cursor location address low word
-
- mov al,o crtc_cloclow ;load register address
- out dx,al
- inc dx
- mov al,bl ;copy lsb to crtc
- out dx,al
-
- ;exit
-
- c1:
- pull bp,di,si,dx,cx,bx,ax ;restore registers
- clc ;indicate no errors
- ret ;exit
-
- ;clear cursor
-
- clear_cursor:
- push ax,bx,cx,dx,si,di,bp ;save registers
- cs mov b cursor_on,0 ;indicate cursor not displayed
- mov bx,-1 ;throw cursor out of range of screen
- cs cmp b chart_active,080h ;is program in dos shell?
- je b1 ;program video hardware directly
- mov ah,1 ;load function parameter
- cs mov bh,b active_page ;load current page
- mov cx,02000h ;cursor will dissapear
- call int10 ;clear cursor
- jmp c1 ;exit
-
- ;Set cursor type
-
- restore_cursor:
- mov cx,w exit_cursor_type ;restore state of cursor
- set_cursor:
- push ax,bx,cx,dx,si,di,bp ;save registers
- cs mov b cursor_on,0ffh ;indicate cursor displayed
- cs cmp b chart_active,080h ;is program in dos shell?
- je >b1 ;program video hardware directly
- mov ah,1 ;load function parameters
- cs mov bh,b active_page ;load current video map page
- call int10 ;set cursor type
- jmp c1 ;exit
-
- ;program cursor hardware directly
-
- b1:
- mov bx,cx ;copy scan rows
- push es ;save segment register
- xor ax,ax ;load zero page
- mov es,ax
- cs mov dx,w crtc_address ;load crtc address register port
-
- ;copy cursor start address
-
- mov al,o crtc_cstart ;load cursor start register address
- out dx,al ;select cursor start address
- mov al,bh ;load cursor
- inc dx ;move to crtc read/write address
- out dx,al
- dec dx ;move to crtc register select address
-
- ;copy cursor end address
-
- mov al,o crtc_cend ;load cursor end register address
- out dx,al ;select cursor end address
- mov al,bl ;load cursor
- inc dx ;move to crtc read/write address
- out dx,al
- es mov w[0460h],bx
- pull es ;restore register
- jmp c1 ;exit
-
- ;display copyright banner to display
-
- copyright_message:
- call cursor ;position cursor
- call write ;write title
- db 'Chart 1.23 Copyright 1992-1993 Andrew Sprott. All rights reserved.',0
- ret ;exit
-
- ;end